/*
-----------------------------------------------------------------------------
This file is part of NxGraphics, Multimedia Engine.
Author : Stephane Kyles. Developed in Prague, Czech Republic.
		_   __       ______                     __     _            
	   / | / /_  __ / ____/_____ ____ _ ____   / /_   (_)_____ _____
	  /  |/ /| |/_// / __ / ___// __ `// __ \ / __ \ / // ___// ___/
	 / /|  /_>  < / /_/ // /   / /_/ // /_/ // / / // // /__ (__  ) 
	/_/ |_//_/|_| \____//_/    \__,_// .___//_/ /_//_/ \___//____/  
									/_/                             
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#ifndef __NXGRAPHICS3DPHYSICSOBJECT_H__
#define __NXGRAPHICS3DPHYSICSOBJECT_H__

#include "NxGraphics_Prerequisites.h"

namespace NxGraphics_Namespace {

enum NxShapeTypes
{  
	ShapeBox,
	ShapeSphere,
	ShapeCapsule,
	ShapePlane,
	ShapeMesh
};

class NxGraphics_Export NxBaseDesc
{
	NxShapeTypes mType;
protected:
	NxBaseDesc( NxShapeTypes Type ) : mType( Type ), mlocalPosition( Ogre::Vector3(0,0,0) ), mlocalOrientation(  Ogre::Quaternion::IDENTITY ){}
public :
	const NxShapeTypes GetType() const { return mType; }
	Ogre::Vector3 mlocalPosition;
	Ogre::Quaternion mlocalOrientation;
};

class NxGraphics_Export NxBoxDesc : public NxBaseDesc
{
public:
	NxBoxDesc() : NxBaseDesc( ShapeBox ){}
	Ogre::Vector3 mDimensions; 
};

class NxGraphics_Export NxSphereDesc : public NxBaseDesc
{
public:
	NxSphereDesc() : NxBaseDesc( ShapeSphere ){}
	float mRadius; 
};

class NxGraphics_Export NxPlaneDesc : public NxBaseDesc
{
public:
	NxPlaneDesc() : NxBaseDesc( ShapePlane ){}
	Ogre::Vector2 mDimensions; 
};

class NxGraphics_Export NxCapsuleDesc : public NxBaseDesc
{
public:
	NxCapsuleDesc() : NxBaseDesc( ShapeCapsule ){}
	float Radius;
	float Height;
};

class NxGraphics_Export NxEntityDesc : public NxBaseDesc
{
public:
	NxEntityDesc() : NxBaseDesc( ShapeMesh ), mUseConvex(false){}
	NxScene3DObjectEntity * mNxEntity;
	bool mUseConvex;
};

class NxGraphics_Export NxParticleDesc
{
public:
	NxParticleDesc() : NumParticles(256){}
	unsigned int NumParticles;
};

class NxGraphics_Export NxClotheDesc
{
public:
	NxClotheDesc(){}
	Ogre::Entity * mEntity;
 
};

class NxGraphics_Export NxPhysicsForceFieldShape
{
public :
	NxPhysicsForceFieldShape( NxForceFieldShape * FieldShape );
	~NxPhysicsForceFieldShape();
	NxForceFieldShape * GetShape();
private :
	NxForceFieldShape * mForceField;

};

class NxPhysicsShape;
class NxPhysicsMeshShape;
class NxGraphics_Export NxPhysicsForceField
{
public :
	//! NxPhysicsForceField Class Constructor.
	NxPhysicsForceField( NxPhysicsShape * Shape );
	//! NxPhysicsForceField Class Destructor.
	~NxPhysicsForceField();
	//! Set Magnetic Force.
	void SetForce( const Ogre::Vector3 & Force );
	//! Set Magnet coordinate type.
	void SetCoordinatesType( const NxEntityMagnetCoordinates Type );
	//! Set Magnet Constant.
	void SetConstant( const Ogre::Vector3 & Constant );
	//! Create a box include Shape.
	NxPhysicsForceFieldShape * CreateIncludeShape( const NxBoxDesc & BoxDesc );
	//! Create a sphere include Shape.
	NxPhysicsForceFieldShape * CreateIncludeShape( const NxSphereDesc & SphereDesc );
	//! create a forcefiled shape from include shapes.
	NxPhysicsForceFieldShape * CreateIncludeShape( NxPhysicsMeshShape * MeshShape );
	//! remove forcefiled shape from include shapes.
	void RemoveIncludeShape( NxPhysicsForceFieldShape * FieldShape );

private:
	NxForceField * mForceField;
};
 
class NxGraphics_Export NxPhysicsShape : public CountedObj<NxPhysicsShape>
{
protected :
	//! NxPhysicsShape Class Constructor.
	NxPhysicsShape( NxPhysicsActor * Actor, const NxBaseDesc & Desc );
public :
	//! NxPhysicsShape Class Destructor.
	virtual ~NxPhysicsShape();
	//! Set Skin Width.
	void SetSkinWidth( float SkinWidth );
	//! Get Skin Width.
	float GetSkinWidth() const;
	//! Set Shape Local Position.
	void SetLocalPosition( const Ogre::Vector3 & Position );
	//! Get Shape Local Position.
	const Ogre::Vector3 & GetLocalPosition() const;
	//! Set Shape Global Position.
	void SetGlobalPosition( const Ogre::Vector3 & Position );
	//! Get Shape Global Position.
	const Ogre::Vector3 & GetGlobalPosition() const;
	//! Set Shape Local Orientation.
	void SetLocalOrientation( const Ogre::Quaternion & Orientation );
	//! Set Shape Local Orientation.
	const Ogre::Quaternion & GetLocalOrientation() const;
	//! Set Shape Global Orientation.
	void SetGlobalOrientation( const Ogre::Quaternion & Orientation );
	//! Get Shape Global Orientation.
	const Ogre::Quaternion & GetGlobalOrientation() const;
	//! Create a Force Field for the Current Shape.
	NxPhysicsForceField * CreateForceField();
	//! Get Shape Type.
	const NxShapeTypes GetType();
	//! Get Physx Shape.
	NxShape * GetNxShape();
protected :
	//! 
	NxShapeTypes mType;
	//! Physx Shape.
	NxShape * mShape;
};

class NxPhysicsBoxShape : public NxPhysicsShape
{
public :
	//! NxPhysicsBoxShape Class Constructor.
	NxPhysicsBoxShape( NxPhysicsActor * Actor, const NxBoxDesc & Desc );
	//! NxPhysicsBoxShape Class Destructor.
	~NxPhysicsBoxShape();
	//! Set Box Dimensions.
	void SetDimensions( const Ogre::Vector3 & Dimension );
	//! Get Box Dimensions.
	const Ogre::Vector3 & GetDimensions() const;
};

class NxPhysicsPlaneShape : public NxPhysicsShape
{
public :
	//! NxPhysicsPlaneShape Class Constructor.
	NxPhysicsPlaneShape( NxPhysicsActor * Actor, const NxPlaneDesc & Desc );
	//! NxPhysicsPlaneShape Class Destructor.
	~NxPhysicsPlaneShape();
};

class NxPhysicsCapsuleShape : public NxPhysicsShape
{
public :
	//! NxPhysicsBoxShape Class Constructor.
	NxPhysicsCapsuleShape( NxPhysicsActor * Actor, const NxCapsuleDesc & Desc );
	//! NxPhysicsBoxShape Class Destructor.
	~NxPhysicsCapsuleShape();
	//! Get Radius.
	float GetRadius();
	//! Get Height.
	float GetHeight();
};

class NxPhysicsMeshShape : public NxPhysicsShape
{
public:
	//! NxPhysicsMeshShape Class Constructor.
	NxPhysicsMeshShape( NxPhysicsActor * Actor, const NxEntityDesc & Desc );
	//! NxPhysicsMeshShape Class Destructor.
	~NxPhysicsMeshShape();
};

class NxGraphics_Export NxPhysicsFluidEmitter
{
public :
	//! NxPhysicsFluidEmitter Class Constructor.
	NxPhysicsFluidEmitter( NxPhysicsFluid * Fluid, NxPhysicsShape * Shape );
	//! NxPhysicsFluidEmitter Class Destructor.
	~NxPhysicsFluidEmitter();
	//! Set Emitter Local Position.
	void SetLocalPosition( const Ogre::Vector3 & Position );
	//! Get Emitter Local Position.
	const Ogre::Vector3 & GetLocalPosition() const;
	//! Set Local Orientation.
	void SetLocalOrientation( const Ogre::Quaternion & Orientation );
	//! Get Local Orientation.
	const Ogre::Quaternion & GetLocalOrientation() const;
	//! Set Emitter Global Position.
	void SetGlobalPosition( const Ogre::Vector3 & Position );
	//! Get Emitter Global Position.
	const Ogre::Vector3 & GetGlobalPosition() const;
	//! Set Emitter Global Orientation.
	void SetGlobalOrientation( const Ogre::Quaternion & Orientation );
	//! Get Emitter Global Orientation.
	const Ogre::Quaternion & GetGlobalOrientation() const;
	//! Set Emitter Max Angle.
	void SetMaxAngle( float Angle );
	//! coefficient The repulsion coefficient in the range from 0 to inf.
	void SetRepulsionCoefficient( float coefficient );
	//! get The repulsion coefficient.
	float GetRepulsionCoefficient() const ;
	//! Set Particle Life Time.
	void SetParticlesLifeTime( float lifeTime );
	//! Get Particles Life time.
	float GetParticleLifeTime();
	//! Set Velocity magnitude.
	void SetVelocityMagnitude( float Velocity );
	//! Set Particles rate : Amount / Second.
	void SetParticlesRate( float Rate );
	//! Enable / Disable the Emitter.
	void SetEnabled( bool Enabled );
private :
	//! NxFluidEmitter.
	NxFluidEmitter * mEmitter;
};

class NxGraphics_Export NxPhysicsFluid 
{
	typedef vector<NxPhysicsFluidEmitter*>::type NxEmitterVector;
	typedef NxVectorIterator<NxEmitterVector> NxEmitterVectorIterator;
public :
	//! NxPhysicsFluidShape Class Constructor.
	NxPhysicsFluid( NxPhysicsActor * Actor, const NxParticleDesc & Desc );
	//! NxPhysicsFluidShape Class Destructor.
	~NxPhysicsFluid();
	//! Create Emitter;
	NxPhysicsFluidEmitter * CreateEmitter( NxPhysicsShape * Shape );
	//! Get NxEmitter iterator;
	NxEmitterVectorIterator GetNxEmitterIterator();
	//! Get NxFluid
	NxFluid * GetNxFluid();
	//! Get NxFluid Max Particles.
	unsigned int GetMaxParticles();
	//! Get Particle Positions.
	const float * GetParticlePositions() const;
	//! Get Current number of emitted particles.
	unsigned int GetNumParticles();
	//! Set particles external force / direction
	void SetExternalAcceleration( const Ogre::Vector3& acceleration );
	//! Particles affected to gravity ?
	void SetGravity( bool GravityAffected );
	//! Set Viscosiy.
	void SetViscosity( float Viscosity );
	//! Sets the restitution used for collision with static shapes. Must be between 0 and 1.
	void SetRestitutionForStaticShapes( float rest );
	//! Sets the dynamic friction used for collision with static actors. Must be between 0 and 1.
	void SetDynamicFrictionForStaticShapes( float Friction );
	//! Sets the static friction used for collision with static actors. Range: [0,inf] default : 0
	void SetStaticFrictionForStaticShapes( float Friction );
	//! Sets the restitution used for collision with dynamic actors. Must be between 0 and 1.	
	void SetRestitutionForDynamicShapes( float rest );
	//! Sets the dynamic friction used for collision with dynamic shapes. Must be between 0 and 1.
	void SetDynamicFrictionForDynamicShapes( float friction );
	//! Sets the static friction used for collision with dynamic shapes. range 0 - inf , default : 0
	void SetStaticFrictionForDynamicShapes( float friction );
	//! coefficient The collision response coefficient (0 or greater).
	void SetCollisionResponseCoefficient( float coefficient );
private:
	//! Physx Fluid
	MyFluid * mFluid;
	//! Physx Fluid.
	NxParticles * mFluidObject;
	//! NxEmitters List.
	NxEmitterVector mNxEmitters;
};

class NxGraphics_Export NxPhysicsActor : public CountedObj<NxPhysicsActor>
{
public :
	//! NxPhysicsActor Class Constructor.
	NxPhysicsActor( NxScene3DObject * Node, const std::string & Name, const PhysicGroup Property );
	//! NxPhysicsActor Class Destructor.
	~NxPhysicsActor();
	//! Create a box shape.
	NxPhysicsBoxShape * CreateBoxShape( const NxBoxDesc & BoxDesc );
	//! Create a Capsule shape.
	NxPhysicsCapsuleShape * CreateCapsuleShape( const NxCapsuleDesc & CapsuleDesc );
	//! Create a plane shape.
	NxPhysicsPlaneShape * CreatePlaneShape( const NxPlaneDesc & PlaneDesc );
	//! Create a mesh shape.
	NxPhysicsMeshShape * CreateMeshShape( const NxEntityDesc & MeshDesc );
	//! Create Fluids.
	NxPhysicsFluid * CreateFluids( const NxParticleDesc & FluidDesc );
	//! is Actor Dynamic ?
	bool IsDynamic();
	//! Get Actors Name.
	const std::string & GetName() const;
	//! Set Actor Global Position.
	void SetPosition( const Ogre::Vector3 & Position );
	//! Get Actors Global Position.
	const Ogre::Vector3 & GetPosition() const;
	//! Set Actors Global Orientation.
	void SetOrientation( const Ogre::Quaternion & Orientation );
	//! Get Actors Global orientation.
	const Ogre::Quaternion & GetOrientation() const;
	//! Add force to the Actor, the Actor must be Dynamic.
	void AddForce( const Ogre::Vector3 & Direction, const float Force );
	//! Set Entity Physic Properties.
	void SetBodyProperties( const PhysicGroup Property );
	//! Get Physic Properties.
	const PhysicGroup GetBodyProperty() const;
	//! Get Physx Actor.
	NxActor * GetNxActor();
private:
	//! Physx Actor.
	NxActor * mActor;
	//! Physx Fluid List;
	std::vector< NxPhysicsFluid * > mFluids;
	//! Actor Physic Property.
	PhysicGroup mPhysicProperty;
};

class NxGraphics_Export NxScene3DObjectSound : public CountedObj<NxScene3DObjectSound>
{
public :
	//! NxScene3DObjectSound Class Constructor.
	NxScene3DObjectSound( const std::string & SoundName, const std::string & SoundFile );
	//! NxScene3DObjectSound Class Destructor.
	~NxScene3DObjectSound();
	//! Set Global Sound Position.
	void SetPosition( const Ogre::Vector3 & Position );
	//! Get Global Sound Position 
	const Ogre::Vector3 & GetPosition() const;
	//! Set Sounds Direction XYZ.
	void SetDirection( const Ogre::Vector3 & Direction );
	//! Set Sounds Range in Meters.
	void SetRange( const Ogre::Vector2 & MinMaxRange );
private :
	NxSoundMediaFile * mSound;
};

class NxGraphics_Export NxScene3DObject
{
private :
	typedef map<std::string, NxScene3DObjectEntity*>::type NxEntityList;
    typedef NxMapIterator<NxEntityList> NxEntityListIterator;

	typedef map<std::string, NxPhysicsActor*>::type NxActorList;
    typedef NxMapIterator<NxActorList> NxActorListIterator;

	typedef map<std::string, NxScene3DObjectLight*>::type NxLightList;
    typedef NxMapIterator<NxLightList> NxLightListIterator;

	typedef map<std::string, NxScene3DObjectCamera* >::type NxCameraList;
	typedef NxMapIterator<NxCameraList> NxCameraMapIterator;

	typedef map<std::string, NxScene3DObjectSound* >::type NxSoundList;
	typedef NxMapIterator<NxSoundList> NxSoundMapIterator;

public :
	//! NxScene3DObject Class Constructor.
	NxScene3DObject( Nx3D_Scene * NxManager, const std::string & NodeName );
	//! NxScene3DObject Class Destructor.
	~NxScene3DObject();
	//! Create NxEntity With Provided Ogre Mesh;
	NxScene3DObjectEntity * CreateNxEntity( const std::string & MeshName );
	//! Create NxBox with provided name;
	NxScene3DObjectEntity * CreateNxBox( const std::string & BoxName, const Ogre::Vector3 & Dimensions, const Ogre::Vector3 & NumSegments = Ogre::Vector3( 5,5,5 ) );
	//! Create NxSphere with provided name;
	NxScene3DObjectEntity * CreateNxSphere( const std::string & SphereName, float Radius );
	//! Create NxCapsule with provided name;
	NxScene3DObjectEntity * CreateNxCapsule( const std::string & CapsuleName, const Ogre::Vector2 & Dimensions );
	//! Create NxCapsule with provided name;
	NxScene3DObjectEntity * CreateNxPlane( const std::string & PlaneName, const Ogre::Vector2 & Dimensions, const Ogre::Vector2 & NumSegments = Ogre::Vector2( 5,5 ) );
	//! Create NxCylinder with provided name;
	NxScene3DObjectEntity * CreateNxCylinder( const std::string & CylinderName, float Radius, float Height );
	//! Create NxCone with provided name;
	NxScene3DObjectEntity * CreateNxCone( const std::string & ConeName, float Radius, float Height );
	//! Create Particles;
	Nx3DObjectPhysicFluid * CreateNxParticles( const std::string & ParticlesName );
	//! Create Clothe;
	Nx3DObjectPhysicClothe * CreateNxCloth( const std::string & ClotheName, const NxClotheDesc & ClotheDesc );
	//! Create a line.
	Nx3DObjectPhysicLine * CreateNxLine( const std::string & LineName );
	//! Create a NxCharacter
	NxScene3DObjectCharacter * CreateNxCharacter( const std::string & CharacterMesh );
	//! Get Attached Object By Name.
	NxScene3DObjectEntity * GetNxEntity( const std::string& MeshName ) const;
	//! Get Attached Objects.
	NxEntityListIterator GetNxEntityIterator();
	//! Create NxActor.
	NxPhysicsActor * CreateNxActor( const std::string & ActorName, const PhysicGroup Property );
	//! Get NxActor iterator;
	NxActorListIterator GetNxActorIterator();
	//! Get NxActor By Name.
	NxPhysicsActor * GetNxActor( const std::string & ActorName ) const;
	//! Create NxLight
	NxScene3DObjectLight * CreateNxLight( const std::string & LightName, const NxLightType Type );
	//! Get NxLight Iterator.
	NxLightListIterator GetNxLightIterator();
	//! Get NxLight By Name.
	NxScene3DObjectLight * GetNxLight( const std::string & LightName ) const;
	//! Create Camera by Name.
	NxScene3DObjectCamera * CreateNxCamera( const std::string & CameraName );
	//! Get Camera By Name.
	NxScene3DObjectCamera * GetNxCamera( const std::string & CameraName ) const;
	//! Get NxCamera Objects Iterator.
	NxCameraMapIterator GetNxCameraIterator();
	//! Create NxSound by Name.
	NxScene3DObjectSound * CreateNxSound( const std::string & SoundName, const std::string & SoundFile );
	//! Get NxSound By Name.
	NxScene3DObjectSound * GetNxSound( const std::string & SoundName ) const;
	//! Get NxSound Objects Iterator.
	NxSoundMapIterator GetNxSoundIterator();
	//! Set Position.
	void SetPosition( const Ogre::Vector3 & Position );
	//! GetPosition.
	const Ogre::Vector3 & GetPosition() const;
	//! Set Orientation.
	void SetOrientation( const Ogre::Quaternion & Orientation );
	//! Get Orientation.
	const Ogre::Quaternion & GetOrientation() const;
	//! Set Scale.
	void SetScale( const Ogre::Vector3 & Scale );
	//! Get Scale.
	const Ogre::Vector3 & GetScale() const;
	//! View debug content.
	void SetDebugEnabled( bool Debug );
	//! Object lifetime;
	void SetLifeTime( float milliseconds );
	//! Get object lifetime.
	float GetLifetime();
	//! is object valid ?
	bool IsValid();
	//! Enable / Disable SceneNode Animation by Name.
	void SetNodeAnimation( const std::string& AnimationName, bool Looped );
	//! Update
	void Update( const float time );
	//! Get Name.
	std::string GetName();
	//! Get Scene Reference
	Nx3D_Scene & GetNxScene();
	//! Get SceneNode.
	Ogre::SceneNode * GetNxSceneNode();
	//! OnMouseMoved
	void OnMouseMoved( const OIS::MouseEvent &e );
	//! OnMousePressed
	void OnMousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	//! OnMouseReleased
	void OnMouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	//! OnKeyPressed
	void OnKeyPressed( const OIS::KeyEvent &e );
	//! OnKeyReleased
	void OnKeyReleased( const OIS::KeyEvent &e );

private :
	//! NxActor List.
	NxActorList mNxActors;
	//! NxLight List.
	NxLightList mNxLights;
	//! NxEntity List.
	NxEntityList mNxEntities;
	//! NxCamera List
	NxCameraList mNxCameras;
	//! NxSound List.
	NxSoundList mNxSounds;
	//! Base Scene Node.
	Ogre::SceneNode * mSceneNode;
	//! object lifetime.
	float mLifetime;
	//! Current time.
	float mCurrentTime;
	//! object valid.
	bool mValid;
	//! NxScene
	Nx3D_Scene * mScene;
};


enum NxEntityQueryFlags
{
  NXENTITY = 1<<0,
  NXTERRAIN = 1<<1,
  NXGIZMO = 1<<2
};

//!  A class to manage basic entities in the 3d scene
class NxGraphics_Export NxScene3DObjectEntity : public CountedObj<NxScene3DObjectEntity>
{
public :
	//! NxScene3DObjectEntity Class Constructor.
	NxScene3DObjectEntity();
	//! NxScene3DObjectEntity Class Constructor.
	NxScene3DObjectEntity( NxScene3DObject * parentNode, const std::string & MeshName );
	//! Destructor
	virtual ~NxScene3DObjectEntity();
	//! Update From Timestep.
	virtual void Update( float time );
	//! Get Entity Type, see NxType;
	const NxType GetNxType();
	//! Get Entity Name.
	const std::string & GetName();
	//! Set position
	virtual void SetPosition( const Ogre::Vector3 & Position );
	//! Get Position
	const Ogre::Vector3 & GetPosition() const;
	//! Set Orientation
	virtual void SetOrientation( const Ogre::Quaternion & Orientation );
	//! Get Orientation
	const Ogre::Quaternion & GetOrientation() const;
	//! translate
	void Translate( const Ogre::Vector3 & Position, int Space );
	//! rotate
	void Rotate( const Ogre::Quaternion & Orientation,  int Space );
	//! get Bounds Size in Local Coordinates.
	const Ogre::Vector3 & GetBoundsSize() const;
	//! Get Entity material Name.
	const std::string & GetMaterialName();
	//! Set Entity Material Name.
	void SetMaterialName( const std::string & MaterialName );
	//! Set NxActor to NxEntity.
	bool SetNxActor( const std::string & ActorName );
	//! Set NxSound to NxEntity.
	bool SetNxSound( const std::string & SoundName );
	//! Set NxEntity To Cast Shadows.
	void SetCastShadows( bool CastShadows );
	//! View debug content.
	virtual void SetDisplayDebug( bool Debug );
	//! set the entity visible
	virtual void SetVisible( bool Visible );
	//! Set Object Selected.
	void SetSelected( bool Selected );
	//!Enable Vertex Animation
	void SetAnimation( const std::string & VertexAnimationName, bool Looped );
	//! Get Ogre Entity.
	Ogre::Entity * GetEntity();
	//! Get Ogre Scene Node.
	Ogre::SceneNode * GetSceneNode();
	//! Get Parent Scene Node;
	Ogre::SceneNode * GetParentSceneNode();
	//! OnMouseMoved
	virtual void OnMouseMoved( const OIS::MouseEvent &e );
	//! OnMousePressed
	virtual void OnMousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	//! OnMouseReleased
	virtual void OnMouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	//! OnKeyPressed
	virtual void OnKeyPressed( const OIS::KeyEvent &e );
	//! OnKeyReleased
	virtual void OnKeyReleased( const OIS::KeyEvent &e );
protected :
	//! Base Type.
	NxType mType;
	//! Parent scene Node
	NxScene3DObject * mNxNodeParent;
	//! Physic Actor, if any.
	NxPhysicsActor * mActor;
	//! NxSound, if any.
	NxScene3DObjectSound * mSound;
	//! Current Object Scene.
	Nx3D_Scene * mScene;
	//! Ogre Entity.
	Ogre::Entity * mEntity ;
	//! Ogre Scene Node.
	Ogre::SceneNode * mNode;
	//! is the Object Selected ?
	bool mIsSelected;
};





class NxGraphics_Export Nx3DObjectPhysicClothe : public NxScene3DObjectEntity 
{
public :
	//! Nx3DObjectPhysicClothe Class Constructor.
	Nx3DObjectPhysicClothe( NxScene3DObject * Parent, const NxClotheDesc & ClotheDesc );
	//! Nx3DObjectPhysicClothe Class Destructor.
	~Nx3DObjectPhysicClothe();
	//! Update.
	void Update( float time );

	void allocateReceiveBuffers( int numVertices, int numTriangles );


	void AttachVertexToGlobalPosition( unsigned int Vertice, const Ogre::Vector3 & Position );
private :

	NxCloth * mCloth;
	Ogre::Entity * mEntity;


	struct RenderBufferVertexElement;
	Ogre::String MatName ;
	Ogre::ManualObject* mManualObj;	
	//!The Recieve buffer that the PhysX SDK return the simulate result every step.
	NxMeshData  * mReceiveBuffers;
	NxScene *mScene;
	//NxCloth *mCloth;
	NxClothMesh *mClothMesh;
	//! The rendering buffers,the most important thing for ogre rendering.
	RenderBufferVertexElement * mVertexRenderBuffer;	
	unsigned int * mIndexRenderBuffer;
	unsigned int mTexId;
	unsigned int mMaxVertices;
	unsigned int mMaxIndices;
	unsigned int mNumIndices;
	unsigned int mNumParentIndices;
	unsigned int mNumVertices;
	unsigned int mLastNumVertices;
	unsigned int mMeshDirtyFlags;
	bool mTeared;
	//! Temporary storage for tex coords
	float *mTempTexCoords;
	unsigned int mNumTempTexCoords;
	unsigned int mTriCount;




};



//!  A class to manage a 3D Physic Fluid Object.
class NxGraphics_Export Nx3DObjectPhysicFluid : public NxScene3DObjectEntity 
{
public:
	//! Nx3DObjectPhysicFluid class Constructor.
	Nx3DObjectPhysicFluid( NxScene3DObject * parentNode, unsigned int NumParticles = 256 );
	//! Nx3DObjectPhysicFluid class Destructor.
	~Nx3DObjectPhysicFluid();
	//! Update Fluids.
	void Update( float time );
	//! Set Particle size.
	void SetParticlesSize( float SizeX, float SizeY );
	//! Set Material Name.
	void SetMaterialName( std::string MaterialName );
	//! Set NxFluids to Particles.
	void SetNxFluids( NxPhysicsFluid * Fluid );
private :
	//! NxFluids if any.
	NxPhysicsFluid * mFluids;
	//! Physx Fluid.
	NxParticles * mFluidObject;
};

class NxGraphics_Export Nx3DObjectPhysicLine : public NxScene3DObjectEntity
{
public :
	//! Nx2DSceneObjectLine class Constructor.
	Nx3DObjectPhysicLine( NxScene3DObject * parentNode );
	//! Nx2DSceneObjectLine class Destructor.
	~Nx3DObjectPhysicLine();
	//! Add Point.
	void AddPoint( Ogre::Real x, Ogre::Real y, Ogre::Real z );
	//! Set Point.
	void SetPoint( unsigned short Index, const Ogre::Vector3 &Value );
	//! Get point Position.
	const Ogre::Vector3 & GetPointPosition( unsigned short Index ) const;
	//! Set Material by Name.
	void SetMaterialName( const std::string & MaterialName );
	//! update Object.
	void Update( float time );
	//! Clear buffer.
	void Clear();
private :
	NxLine * mLines;
};

//!  A class to manage Lights in the 3d scene
class NxGraphics_Export NxScene3DObjectLight : public NxScene3DObjectEntity 
{
public :
	//! NxScene3DObjectLight Class Constructor.
	NxScene3DObjectLight( NxScene3DObject * ParentNode, const std::string & LightName, NxLightType Type );
	//! NxScene3DObjectLight Class Destructor.
	~NxScene3DObjectLight();
	//! Update Light;
	void Update( float time );
	//! Set Light Position.
	void SetPosition( const Ogre::Vector3 & Position );
	//! Set Light Intensity if Applicable.
	void SetIntensity( float Intensity );
	//! Set Light Diffuse Colour.
	void SetDiffuseColour( const Ogre::ColourValue & Colour );
	//! Set light Specular Colour.
	void SetSpecularColour( const Ogre::ColourValue & Colour );
	//! Set Light Type.
	void SetLightType( const NxLightType & Type );
	//! Get Light Type.
	const NxLightType & GetLightType() const;
	//! Set Light Direction If Applicable.
	void SetDirection( const Ogre::Vector3 & Direction );
	//! Set Light Cone Angle If Applicable.
	void SetConeAngle( float Angle );
	//! Set Frustrum Near And Far Plane.
	void SetFrustum( float NearPlane, float FarPlane );
	//! Set Projective Texture.
	void SetTexture( const std::string & TextureName );
	//! View Light Debug.
	void SetDebugEnabled( bool Debug );
private :
	Ogre::Light * mLight;
};

//!  A class to manage a 3D Physic Cloth Object.
class NxGraphics_Export Nx3DObjectPhysicCloth : public NxScene3DObjectEntity 
{
public:
	//Nx3DObjectPhysicCloth Class Constructor.
	Nx3DObjectPhysicCloth( Ogre::SceneNode * EntitySceneNode );
	//Nx3DObjectPhysicCloth Class Destructor.
	~Nx3DObjectPhysicCloth();
	//Get Physx NxCloth.
	NxCloth * GetNxCloth();
	//!Detach Cloth From Any Attached Object
	void DetachCloth();
	//! Set Cloth Material by Name.
	void SetMaterialName( Ogre::String MaterialName );	
	//! Update Cloth.
	void Update( float time ); 
private:
	bool Create( NxClothDesc &desc, char *objFileName, float scale, NxVec3* offset, char *texFilename   );
	void render();	
	struct RenderBufferVertexElement;
	Ogre::String MatName ;
	Ogre::ManualObject* mManualObj;	
	//!The Recieve buffer that the PhysX SDK return the simulate result every step.
	NxMeshData  * mReceiveBuffers;
	NxScene *mScene;
	NxCloth *mCloth;
	NxClothMesh *mClothMesh;
	//! The rendering buffers,the most important thing for ogre rendering.
	RenderBufferVertexElement * mVertexRenderBuffer;	
	unsigned int * mIndexRenderBuffer;
	unsigned int mTexId;
	unsigned int mMaxVertices;
	unsigned int mMaxIndices;
	unsigned int mNumIndices;
	unsigned int mNumParentIndices;
	unsigned int mNumVertices;
	unsigned int mLastNumVertices;
	unsigned int mMeshDirtyFlags;
	bool mTeared;
	//! Temporary storage for tex coords
	float *mTempTexCoords;
	unsigned int mNumTempTexCoords;
	unsigned int mTriCount;
	void init( NxScene * scene, NxClothDesc &desc, NxClothMeshDesc &meshDesc );
	bool generateObjMeshDesc( NxClothMeshDesc &desc, char *filename, float scale, NxVec3* offset, bool textured );
	void generateTearLines( NxClothMeshDesc& desc, unsigned int w, unsigned int h );
	void releaseMeshDescBuffers( const NxClothMeshDesc& desc );
	bool cookMesh(NxClothMeshDesc& desc);
	void allocateReceiveBuffers(int numVertices, int numTriangles);
	void releaseReceiveBuffers();
	bool mInitDone;
};

//!  A class to manage a 3D Physic Magnet Object.
class NxGraphics_Export Nx3DObjectPhysicMagnet : public NxScene3DObjectEntity 
{
public:
	//! Nx3DObjectPhysicMagnet class Constructor.
	Nx3DObjectPhysicMagnet( Ogre::SceneNode * EntitySceneNode );
	//! Nx3DObjectPhysicMagnet class Destructor.
	~Nx3DObjectPhysicMagnet();
	//! Set Magnet Force.
	void SetMagnetForce( const Ogre::Vector3 & Force );
	//! Set offset position
	void SetMagnetOffsetPosition( const Ogre::Vector3 & Position );
	//! Set Magnet coordinate type.
	void SetMagnetCoordinatesType( NxEntityMagnetCoordinates Type );
	//! Set Magnet Constant.
	void SetMagnetConstant( const Ogre::Vector3 & Constant );
	//! Set magnet influence size, The dimensions are the 'radii' of the box, meaning 1/2 extents in x dimension, 1/2 extents in y dimension, 1/2 extents in z dimension. 
	void SetMagnetInfluenceSize( const Ogre::Vector3 & Influence );
	//! Update Magnet.
	void Update( float time ); 
private:
	//! Instances of this object automate the application of forces onto rigid bodies, fluid, soft bodies and cloth.
	NxForceField * mPhysicsForceFieldMagnet;
	//! Box shaped region used to define force field.
	NxBoxForceFieldShape * mForceFieldShape;
	//! ForceField include Group.
	NxForceFieldShapeGroup * mExcludeGroup;
};



//!  A class to manage characters in the 3d scene
class NxGraphics_Export NxScene3DObjectCharacter : public NxScene3DObjectEntity 
{
public :
	//! NxScene3DObjectCharacter class Constructor.
	NxScene3DObjectCharacter( NxScene3DObject * node );
	//! NxScene3DObjectCharacter class Deconstructor.
	~NxScene3DObjectCharacter();
	//! Create Character with provided mesh and skeleton.
	void CreateCharacter( const std::string & CharacterMesh );
	//! Set Characters Position.
	void SetPosition( const Ogre::Vector3 & Position );
	//! Get Characters Position.
	const Ogre::Vector3 & GetPosition() const;
	//! Set Characters Orientation.
	void SetOrientation( const Ogre::Quaternion & Orientation );
	//! Get Characters Orientation.
	const Ogre::Quaternion & GetOrientation() const;
	//! Set Characters Scale
	void SetScale( const Ogre::Vector3 & Scale );
	//! Get Scale.
	const Ogre::Vector3 & GetScale() const;
	//! Update Animation Time.
	void Update( float time );
	//! Set Character navigation mode. see NavigationMode
	void SetNavigationMode( NavigationMode Mode);
	//! Set Character deplacement Speed, Meters / second
	void SetCharacterSpeed( float Speed );
	//! Set Character Animation.
	void SetAnimation( const std::string & AnimationName, bool Looped );
	//! get camera bundle associated with this character
	NxScene3DObjectCamera * GetNxCamera();
	//! Set Characters Mocap Data.
	void SetMocapData( std::vector< NxMocapJoint *> MocapData );
	//! Set Character Bone Orientation.
	void SetBoneOrientation( NxMocapJoint Joint );
	//! Set Character Bone Position.
	void SetBonePosition( NxMocapJoint Joint );

	//! Calibrate Character from Current Pose.
	void Calibrate( bool Calibrate );
	
	void Kill( bool Kill );
	void SetRagdollVisible( bool Visible );
	void SetVisible( bool Visible );
	void SetMagnetic( bool Magnetic );
	

	void AddProp( NxScene3DObjectEntity * prop, std::string BoneName, Ogre::Vector3 Offset ); 
	void AjustClothVertexToBone( Nx3DObjectPhysicCloth * Cloth, int VertexIndex, const std::string& BoneName, Ogre::Vector3 Offset );
	void AttachClothVertexToBone( Nx3DObjectPhysicCloth * Cloth, int VertexIndex, const std::string& BoneName, Ogre::Vector3 Offset );
	void SetMaterialName( const std::string & MaterialName );
	Ogre::Skeleton * GetSkeleton();
	Ogre::Entity * GetEntity();
	void UpdatePhysx();



private:

	//!mouse and keys callback
	void OnMouseMoved( const OIS::MouseEvent &e );
	void OnMousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	void OnMouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	void OnKeyPressed( const OIS::KeyEvent &e );
	void OnKeyReleased( const OIS::KeyEvent &e );

	//! Create Character ragdoll.
	void CreatePhysXRagdoll();
	//! Delete Character ragdoll.
	void DeletePhysXRagdoll();
	//! Create Character Joints.
	void CreatePhysxJoints();

		
	void InitializeBoneState( const std::string& Name, const Ogre::Radian& Angle, const Ogre::Vector3 Axis );
	void InitializeBoneState( const std::string& name, const Ogre::Degree& yaw, const Ogre::Degree& pitch,const Ogre::Degree& roll );
	void InitializeBoneState( const std::string& name, const Ogre::Quaternion& q );
	void TransformBone( const std::string& BoneName, Ogre::Matrix3 RotInfo, bool flip );
 
	Ogre::Entity * mCharacterEntity;
	Ogre::SkeletonInstance * mCharacterSkeleton;
	Nx3D_Scene * mCharacterScene;
	float mCharacterPosOffsetX;
	float mCharacterPosOffsetY;
	float mCharacterPosOffsetZ;
	float mCharacterPosOffsetScale;

	
	//boost::mutex * Locker;
	typedef std::map< Ogre::Bone *, NxScene3DObjectEntity * > BindingBoneActors;
	BindingBoneActors NxPropsCollection;// for props
	BindingBoneActors BonesActorsMap;//for bones ragdoll
	bool IsDead;
	std::vector< NxActor * > CharacterPhysxNodes;

	typedef struct
	{
		Ogre::Quaternion QuatParent ;
		Ogre::Quaternion QuatOffset ;
		Ogre::Bone * CurrentBone ;
		Ogre::Quaternion CurrentOrientation;
		Ogre::Vector3 CurrentPosition;
		bool IsRoot;
	} MocapBoneData ;

	typedef std::map< std::string, MocapBoneData > MasterMocapBones;
	MasterMocapBones  BoneFinal;

	typedef std::map< std::string, int > MasterMocapList;
	MasterMocapList  mocapdef;

	std::vector<std::string> BoneListNames ;


	NxScene3DObjectCamera * mCharacterCamera;
	
};

//!  A class to manage camera controllers in the 3d scene
class NxScene3DObjectCameraCallback;
class NxGraphics_Export NxScene3DObjectCamera : public NxScene3DObjectEntity 
{
public :
	//! NxScene3DObjectCamera Class Constructor.
	NxScene3DObjectCamera( NxScene3DObject * ParentNode, const std::string & CameraName );
	//! NxScene3DObjectCamera Class Destructor.
	~NxScene3DObjectCamera();
	//! Create a Capsule Based Character Controller
	void CreateCharacterController( float radius, float height);
	//! Deletes the Character controller
	void DeleteCharacterController();
	//! set character controller height.
	void SetCharacterControllerHeight( float Height );
	//! Set Character height
	void SetCharacterHeight( float Height );
	//! Set Character Radius 
	void SetCharacterRadius( float Radius );
	//! Set Step Offset.
	void SetStepOffset( float Offset );
	//! Set Controller Position
	void SetPosition( Ogre::Vector3 Pos );
	//! Get Controller Position
	const Ogre::Vector3& GetPosition();
	//! Sets aspect ratio for active camera.
    /*!
	  \param AspectRatio the aspect ration to set .
      \sa GetNxCameraOrientation
    */
	void SetAspectRatio( float AspectRatio );
	//! Gets aspect ratio value for active camera.
	float GetAspectRatio();
	//! Sets near plane for active camera.
    /*!
	  \param NearDistance the near distance to set .
      \sa GetNxCameraNearPlane
    */
	void SetNearPlane( Ogre::Real NearDistance );
	//! Gets near plane value for active camera.
	float GetNearPlane();
	//! Sets far plane for active camera.
    /*!
	  \param FarDistance the far distance to set .
      \sa GetNxCameraFarPlane
    */
	void SetFarPlane( Ogre::Real FarDistance );
	//! Gets far plane value for active camera.
	float GetFarPlane();
	//! Look At
	void LookAt( Ogre::Vector3 Target );
	//! Set the camera to orthogonal view
	void SetProjectionType( bool Orthogonal );
	//! Set the polygon view for active camera
    /*!
	  \param PolyMode the view mode to set
      \sa GetNxCameraRotationSpeed
    */
	void SetPolygonView( Ogre::PolygonMode PolyMode );
	//! get the polygon view for active camera
	Ogre::PolygonMode GetPolygonView();
	//! Set Field Of View, In Degrees.
	void SetFieldOfView( float AngleDegree );
	//! get Field Of View Angle, In Degrees.
	float GetFieldOfView();
	//! Updates the Character controller
	void Update( float time );
	//! Gets the Character Controller Physx Actor.
	NxActor * GetCharacterActor();
	//! Gets the Character Controller.
	NxController * GetCharacterController(); 
	//! Gets the Camera Associated with the Character Controller Fps
	Ogre::Camera * GetCameraFps();
	//! Gets the Camera Associated with the Character Controller External View
	Ogre::Camera * GetCameraCharacter();
	//! Sets the Character Controller Collision
	void SetCollisionDetection( bool Collision );
	NavigationMode GetNavigationMode();
	void SetNavigationMode( NavigationMode Mode);
	
	void SetOrientationSpeed( const Ogre::Degree &  Rotspeed );
	const Ogre::Degree &  GetOrientationSpeed();
	void SetNxCameraSpeed( float TransSpeed );
	void ProcessKeyActions( float Delta );

	void SetNxCharacter( NxScene3DObjectCharacter * Character );
	//! set the bundle set active.
	void SetActive( bool Active );
	//! Is Bundle set active.
	bool IsActive();
	
	//virtuals
	void OnMouseMoved( const OIS::MouseEvent &e );
	void OnMousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	void OnMouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id );

	void OnKeyPressed( const OIS::KeyEvent &e );
	void OnKeyReleased( const OIS::KeyEvent &e );

	void UpdateSoundListener();

	enum WalkMode
	{ 
		ModeStandUp,
		ModeCrouchDown
	};
	void SetWalkMode( WalkMode Mode ); // StandUp, CrouchDown, RunForward , WalkForward, 
	WalkMode GetWalkMode(); 

	void StartJump( float Amplitude );
	void StopJump();

	enum TranslateMode
	{
		TranslateForward,
		TranslateBackWard,
		TranslateLeft,
		TranslateRight,
		TranslateUp,
		TranslateDown,
		TranslateNone

	};

	void CameraRotate( float Yaw, float Pitch );
	void CameraTranslate( NxScene3DObjectCamera::TranslateMode Mode );
	TranslateMode GetTranslateMode();
	TranslateMode mTranslateMode;

	NxScene3DObjectCameraCallback * mCallback;

private:

	Ogre::Camera * NxCameraOtherView;
	Ogre::Camera * NxCamera ;
	Ogre::SceneNode* mCameraPivot;
	Ogre::SceneNode* mCameraGoal;
	Ogre::SceneNode* mCameraNode;
	Ogre::Real mPivotPitch;   
	Ogre::Vector3 mGoalDirection;   
	Ogre::SceneNode * NxCharacterNode;

	Ogre::Vector3 mDisplacement; 

	Ogre::Vector3 m_NewCamPosition;

	float m_CameraSpeed;
	float mDeltaTime;
	Ogre::Radian mRotX, mRotY;
	Ogre::Vector3 mTranslateVector;
	Ogre::Real mMoveSpeed;
	Ogre::Degree mRotateSpeed;
	float mMoveScale;
	Ogre::Degree mRotScale;

	//! Moves the Character controller
	void Move( const NxVec3 &disp, unsigned int &flag );
           
	void SetActiveCamera( const std::string & CameraName );

	bool mActive;

	
	NxController* mController;
	NavigationMode mNavigationMode;

	float WalkStandUpHeight;
	float WalkCrouchHeight;
	bool ExtendCharacter ;
	NxScene * CurrentNxScene;

	bool PxJump;  
	float PxV0;
	float PxJumpTime;
	float G;  
	float NxCharacterSpeed; 
	float GetHeight( float elapsedTime );

	WalkMode CurrentWalkMode ;
	void UpdateCharacterExtents( WalkMode Mode );

};

class NxGraphics_Export NxScene3DObjectTree : public NxScene3DObjectEntity
{
public:
	NxScene3DObjectTree( NxScene3DObject * TreeSceneNode );
	~NxScene3DObjectTree();
	void Update( float time );

};

struct NxGraphics_Export NxTerrainLayerDesc {

	//! worldSize = 100, terrainsize 1000, 10 tiles.
	float mWorldSize;
	//! diffuse and normal map.
	std::vector<std::string> mTextures;
	float mMinHeight;
	float mFadeDistance;
};

class NxGraphics_Export NxTerrainDesc  
{
public:
	NxTerrainDesc(){}
	float mWorldSize;
	short mTerrainSize;
	short mMinBatch; 
	short mMaxBatch;
	float mInputScale;
	Ogre::Vector3 mTerrainPosition;
	std::string mHeightMap;
	std::string mGlobalColourMap;
	std::string mCompositeMap;
	float mCompositeMapDistance;
	std::string mLightMap;
	Ogre::Vector3 mLightDirection;
	Ogre::ColourValue mCompositeMapAmbient;
	Ogre::ColourValue mCompositeMapDiffuse;
	std::vector<NxTerrainLayerDesc> mTextureLayerList;
};

class NxGraphics_Export NxScene3DObjectTerrain : public NxScene3DObjectEntity
{
public:
	//! NxScene3DObjectTerrain Constructor.
	NxScene3DObjectTerrain( Nx3D_Scene * mManager, const NxTerrainDesc & TerrainDesc );
	//! NxScene3DObjectTerrain Destructor.
	~NxScene3DObjectTerrain();
	//! Create Paged Grass.
	NxScene3DObjectPagedGrass * CreatePagedGrass( const NxPagedGrassDesc & GrassDesc );
	//! Create Paged Entities.
	NxScene3DObjectPagedEntities * CreatePagedEntities( const NxPagedEntitiesDesc & EntitiesDesc );
	//! get Height at 2D position.
	float GetHeightAtPosition( float X, float Z );
	//! Get Terrain Group.
	Ogre::TerrainGroup * GetTerrainGroup();
	//! Get Terrain Options.
	Ogre::TerrainGlobalOptions * GetTerrainOptions();
	//! Update If Needed.
	void Update( float time );
private :
	Ogre::TerrainGlobalOptions * mTerrainGlobals;
	Ogre::TerrainGroup * mTerrainGroup;
	Nx3D_Scene * mScene;
	std::vector<NxScene3DObjectPagedGrass*> mPagedGrass;
	std::vector<NxScene3DObjectPagedEntities*> mPagedEntities;
};

class NxGraphics_Export NxPagedGrassLayerDesc  
{
public:
	NxPagedGrassLayerDesc(){}
	//! Sets the boundaries of the density / color maps
	Ogre::Vector4 mBounds;
	std::string mMaterialName;
	std::string mDensityMap;
	std::string mColorMap;
	//! Density Map Channel to Use( 0:Color, 1:Red, 2:Green, 3:Blue, 4:Alpha )
	unsigned int mDensityMapChannel;
	//! Sets the maximum density (measured in grass quads/billboards per square unit) of grass 
	float mDensity;
	Ogre::Vector2 mMinMaxSize;
	float mSwayDistribution;	
	float mSwayLength;
	float mSwaySpeed;
};

class NxGraphics_Export NxScene3DObjectPagedGrassLayer
{
public :
	NxScene3DObjectPagedGrassLayer( NxScene3DObjectPagedGrass * Grass, const NxPagedGrassLayerDesc & GrassLayerDesc );
	~NxScene3DObjectPagedGrassLayer();

};

class NxGraphics_Export NxPagedGrassDesc  
{
public:
	NxPagedGrassDesc(){}
	float mPageSize;
	float mMaxRange; 
};

class NxGraphics_Export NxScene3DObjectPagedGrass
{
public :
	NxScene3DObjectPagedGrass( Ogre::Camera * Cam, NxScene3DObjectTerrain * Terrain, const NxPagedGrassDesc & GrassDesc );
	~NxScene3DObjectPagedGrass();
	NxScene3DObjectPagedGrassLayer * AddLayer( const NxPagedGrassLayerDesc & GrassLayer );
	void Update( float time );
	Forests::PagedGeometry * GetGrass();
private:
	Forests::PagedGeometry * mGrass;
};

class NxGraphics_Export NxPagedEntitiesDesc  
{
public:
	NxPagedEntitiesDesc(){}
	float mPageSize;
	float mPageDistance;
	float mPageDistanceFade;
	float mImpostorDistance;
	float mImpostorDistanceFade ;	 
	Ogre::Vector4 mBounds;
	std::string mLightMap;
	std::string mMeshName;
	unsigned int mMeshAmount;
};

class NxGraphics_Export NxScene3DObjectPagedEntities
{
public :
	NxScene3DObjectPagedEntities( Ogre::Camera * Cam, NxScene3DObjectTerrain * DstTerrain, const NxPagedEntitiesDesc & EntitiesDesc );
	~NxScene3DObjectPagedEntities();
	void Update( float time );
private:
	Forests::PagedGeometry * mEntities;
};
 
class NxGraphics_Export NxScene3DObjectVehicule : public NxScene3DObjectEntity
{
public:
	NxScene3DObjectVehicule( NxScene3DObject * VehiculeSceneNode, const std::string & ChassiName );
	~NxScene3DObjectVehicule();
	void Update( float time );
	void OnMouseMoved( const OIS::MouseEvent &e );
	void OnMousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	void OnMouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id );
	void OnKeyPressed( const OIS::KeyEvent &e );
	void OnKeyReleased( const OIS::KeyEvent &e );
 
};

}

#endif